#ifndef POLHEMUS_FRAME_H
#define POLHEMUS_FRAME_H

#ifdef _WINDOWS
#include <tchar.h> // needed to define _T macro used in PDI_90/Inc/PDI.h (VC0 version of PDI.h)
#include "PDI.h"
#endif

#define POL_ERROR_MSG_SIZE  254
#define POL_MAX_STATIONS	4
#define POL_MAX_SENSORS		16
#define POL_MAX_ITEMS		30

/** This class helps to decode information in an output frame.
 *  The Initialize function will retrieve information about the current
 *  configuration for the Polhemus tracker (e.g., active station, number
 *  of sensor, output frame format for the station). The Decode functions 
 *  will decode the frame information, which can then be retrieved using the 
 * Get functions.
 */
class PolhemusFrame {
public:
	 /** make a description of the output format for the Decode functions.
     * @pdiDev pointer toward Polhemus device.
     * @return true/false success/failure
     **/
#ifdef _WINDOWS
	int initialize(CPDIdev &pdiDev);
#endif

	/** Decode a frame in the binary format. Results can be accessed 
	  * with the Get functions.
      * @frame pointer toward position of the header in the P&O buffer.
      * @return true/false success/failure
      **/
	int decodeBinaryFrame(const unsigned char *frame);

	/** Get sensor position 
     * @sensor 
	 * @val pointer toward array of float where to store the sensor position
     * @return true/false success/failure
     */
	int getPosition(int sensor,float *val);

	/** Get sensor orientation
     * @sensor 
	 * @val pointer toward array of float where to store the sensor orientation
     * @return true/false success/failure
     */
	int getOrientation(int sensor,float *val);

	/** Get external frame count
     * @sensor 
	 * @val reference toward frame count
     * @return true/false success/failure
     */
	int getFrameCount(int sensor,unsigned long &val);

	/** Get external sync
     * @sensor 
	 * @val reference toward external sync
     * @return true/false success/failure
     */
	int getExtSync(int sensor, unsigned long &val);

	/** Get the size of the output frame
     * @return the number of bytes of the output frame
     */
	int getFrameSize(void);

	/** Get a string with information on the error
     * @return a pointer toward the string with the error information
     */
	int getErrorInfo(void);

private:
	/* Parse error codes
	*/
	void parseErrorCode(unsigned char error);

	int numSensors;					  // number of activated sensors
	int sensorNb[POL_MAX_STATIONS+1]; // map station number to sensor number
	int stationNb[POL_MAX_STATIONS];  // map sensor number to station number

	// description of an output frame
	short items[POL_MAX_ITEMS];				// descripion of the items in a frame
	int numItems;							// total number of items per frame
	int frameSize;							// total size of a frame (in bytes)
	// these variable store info contained in an frame
	float position[POL_MAX_SENSORS][3];			// PDI_MODATA_POS;  PDI_MODATA_POS_EP:
	float orientation[POL_MAX_SENSORS][3];		// PDI_MODATA_ORI; PDI_MODATA_ORI_EP: 
	float dirCosine[POL_MAX_SENSORS][9];		// PDI_MODATA_DIRCOS: 
	float quaternions[POL_MAX_SENSORS][4];		// case PDI_MODATA_QTRN: 
	unsigned long timeStamp[POL_MAX_SENSORS];	// PDI_MODATA_TIMESTAMP: 
	unsigned long frameCount[POL_MAX_SENSORS];	// PDI_MODATA_FRAMECOUNT: 
	unsigned long stylusFlag[POL_MAX_SENSORS];	// PDI_MODATA_STYLUS: 
	unsigned long distorsionLevel[POL_MAX_SENSORS];	    // PDI_MODATA_DISTLEV: 
	unsigned long extSync[POL_MAX_SENSORS];				// PDI_MODATA_EXTSYNC: 
	//
	char errorMsg[POL_ERROR_MSG_SIZE];
};

#endif // POLHEMUS_FRAME_H
